#include "protocol.h"
#include <QDebug>
#include "action.h"
#include "DbConnection.h"
#include "treedoc.h"
#include "textedit.h"
#include "vtable.h"

Protocol::Protocol(Disparition* parent, Action* Owner): DocEntity(parent),m_owner(Owner)//, m_author(0)
{
    DbConnection::QueryResult res = dynamic_cast<TreeDoc*>(treeWidget())
                                    ->execute("select * from =schema=.ex_operations where element_type=3");
    if(res.success())
    {
        for(int i=0;i<res.rows();i++)
        {
            QAction* action=new QAction(res.at(i,2).toString(),this);
            if(res.at(i,1).toInt()==4)
            {
                connect(action,SIGNAL(triggered()),this,SLOT(appendAction()));
                action->setIcon(QIcon(":/add_entity"));
            }
            if(res.at(i,1).toInt()==7)
            {
                connect(action,SIGNAL(triggered()),this,SLOT(save()));
                action->setIcon(QIcon(":/save_entity"));
            }
            if(res.at(i,1).toInt()==11)
            {
                connect(action,SIGNAL(triggered()),this,SLOT(remove()));
                action->setIcon(QIcon(":/delete_entity"));
            }
            if(res.at(i,1).toInt()==16)
            {
                connect(action,SIGNAL(triggered()),this,SLOT(check()));
                action->setIcon(QIcon(":/check"));
            }
            if(res.at(i,1).toInt()==17)
            {
                connect(action,SIGNAL(triggered()),this,SLOT(approve()));
                action->setIcon(QIcon(":/approve"));
            }
            if(action!=0) operations()->addOperation(res.at(i,1).toInt(),action);
        }
        QAction* action = new QAction(QIcon(":/refresh"),tr("Обновить"),this);
        connect(action,SIGNAL(triggered()),this,SLOT(refresh()));
        operations()->addOperation(50,action);
        operations()->setEnabled(50,true);
    }
}
bool Protocol::removeFromDB()
{
    return dynamic_cast<TreeDoc*>(treeWidget())
                                    ->execute(tr("select =schema=.ex_delete_protocol(%1)").arg(id())).success();
}
void Protocol::giveBithTo()
{
    DbConnection::QueryResult res=dynamic_cast<TreeDoc*>(treeWidget())->
                              execute(tr("select * from =schema=.ex_actions where protocol=%1").arg(id()));
    if(res.success())
    for(int i=0;i<res.rows();i++)
    {
        Action* item=new Action(this);
        item->blockSignals(true);
        item->setID(res.at(i,0).toInt());
        item->setNum(res.at(i,2).toInt());
        item->setContent(res.at(i,3).toString());
        QStringList prf = res.at(i,4).toString().replace(QRegExp("[{}]"),"").split(",");
        foreach(QString id, prf) item->appendPerformer(id.toInt());
        item->setExpiry(res.at(i,5).toDate());
        item->setState(res.at(i,6).toInt());
        item->setNote(res.at(i,7).toString());
        item->blockSignals(false);
        if(dynamic_cast<TreeDoc*>(treeWidget())->highlight()) emit newItem(item);
        QStringList ops = res.at(i,8).toString().replace(QRegExp("[{}]"),"").split(",",QString::SkipEmptyParts);
        if(ops.count()==0) continue;
        foreach(QString id,ops)
        {
            item->operations()->setEnabled(id.toInt(),true);
            if(id.toInt()==8)
            {
                item->operations()->setEnabled(100,true);
                item->operations()->setEnabled(200,true);
            }
        }
    }
}
void Protocol::refresh(const RefreshType &refreshType)
{

     TreeDoc* tree= dynamic_cast<TreeDoc*>(treeWidget());
     DbConnection::QueryResult res= tree->
                                  execute(tr("select * from =schema=.ex_protocols where eid=%1").arg(id()));
     if(res.success())
     {
            blockSignals(true);
            setID(res.at(0,0).toInt());
            setNum(res.at(0,2).toInt());
            setCauses(res.at(0,3).toString());
            setAuthor(tree->users()->user(res.at(0,4).toInt()));
            setState(res.at(0,6).toInt());
            blockSignals(false);
            operations()->turnOff();
            operations()->setEnabled(50,true);
            QStringList ops = res.at(0,7).toString().replace(QRegExp("[{}]"),"").split(",",QString::SkipEmptyParts);
            if(ops.count()>0)
                foreach(QString id,ops) operations()->setEnabled(id.toInt(),true);

    }
    if(refreshType==Himself)
    {
        emit wasRefresh();
        emit childWakedUp(this);
    }
    if(refreshType==Children)
    {
        for(int i=0;i<childCount();i++)
            dynamic_cast <Action*>(child(i))->refresh(Children);
    }
}
QWidget* Protocol::view(DocEntity::ViewTypes viewType)
{
    QWidget* widget = new QWidget(treeWidget());
    QVBoxLayout* main = new QVBoxLayout;
    main->setContentsMargins(0,0,0,0);
    QGroupBox* gbox = new QGroupBox(text(0),widget);
    QVBoxLayout* vlay = new QVBoxLayout;
    gbox->setLayout(vlay);
    vlay->addWidget(new QLabel(tr("Причина несоответствия")));
    TextEdit* w_causes = new TextEdit(widget);
    w_causes->setText(m_causes);
    w_causes->setReadOnly(!operations()->isEnabled(7));
    vlay->addWidget(w_causes);
    connect(w_causes,SIGNAL(textChanged(QString)),this,SLOT(setCauses(QString)));
    main->addWidget(gbox);
    if(viewType==Normal)
    {
        QHBoxLayout* hlay = new QHBoxLayout;
        QVBoxLayout* l_vlay = new QVBoxLayout;
        QVBoxLayout* r_vlay = new QVBoxLayout;
        hlay->addLayout(l_vlay);
        hlay->addStretch();
        hlay->addLayout(r_vlay);
        vlay->addLayout(hlay);
        QLineEdit* line = new QLineEdit(widget);
        line->setReadOnly(true);
        line->setEnabled(false);
        QString name;
        if(author()==0) name=tr("Ошибка: невозможно назначить инициатора"); else name=author()->name();
        line->setText(name);
        l_vlay->addWidget(new QLabel(tr("Инициатор"),widget));
        r_vlay->addWidget(line);
        line = new QLineEdit(widget);
        line->setReadOnly(true);
        line->setEnabled(false);
        line->setText(status());
        l_vlay->addWidget(new QLabel(tr("Статус"),widget));
        r_vlay->addWidget(line);

        vTable* table = new vTable(widget);
        int n=0;
        for(int i=0;i<childCount();i++)
            if(!child(i)->isHidden()) n++;
        table->setSize(n,4);
        table->setColSettings("5%;55%;20%;15%");
        table->setHorizontalHeaderLabels(QStringList()<<tr("№")<<tr("Содержание")<<tr("Срок исполнения")<<tr("Статус"));
        int k=0;
        for(int i=0;i<childCount();i++)
        {
            Action* item = dynamic_cast<Action*>(child(i));
            if(item->isHidden()) continue;
            table->setCell(k,0,item->num());
            table->setCell(k,1,item->content());
            table->setCell(k,2,item->expiry());
            table->setCell(k,3,item->status());
            k++;
        }
        connect(table,SIGNAL(cellActivated(int,int)),this,SLOT(onTableItemClick(int,int)));
        gbox = new QGroupBox(tr("Мероприятия"),widget);
        vlay = new QVBoxLayout;
        vlay->addWidget(table);
        gbox->setLayout(vlay);
        main->addWidget(gbox);
    }
    widget->setLayout(main);
    return widget;
}

QString Protocol::capTemplate()
{
    return tr("Протокол");
}

void Protocol::onTableItemClick(int row, int column)
{
    emit childWakedUp(dynamic_cast<DocEntity*>(child(row)));
}

void Protocol::setCauses(const QString &Causes)
{
    m_causes=Causes;
    emit changed();
}

void Protocol::setAuthor(User *Author)
{
    m_author=Author;
    emit changed();
}

User* Protocol::author()
{
    return m_author;
}

QString Protocol::causes() const
{
    return m_causes;
}

void Protocol::appendAction()
{
    Action* item = new Action(this);
    item->setID(0);
    item->setNum(childCount());
    treeWidget()->setCurrentItem(item);
    item->operations()->setEnabled(100,true);
    item->operations()->setEnabled(200,true);
    item->operations()->setEnabled(8,true);
    item->operations()->setEnabled(12,true);
    item->setState(400);
    emit newItem(item);
    emit childWakedUp(item);
}
bool Protocol::saveToDB()
{
    bool ok=isCorrect(), stop=false;
    if(!ok) return false;    
    if(id()==0)
    {
        QString sql="select =schema=.ex_append_protocol(%1,%2,'%3'::text,%4)";
         sql=sql.arg(parent()->id()).arg(num()).arg(causes()).arg(owner()==0?"NULL":tr("%1").arg(owner()->id()));
        DbConnection::QueryResult res = dynamic_cast<TreeDoc*>(treeWidget())->execute(sql);
        if(res.success())
            setID(res.at(0,0).toInt());
        else
            ok=false;
    }
    else
    {
        QString sql="select =schema=.ex_change_protocol(%1,'%2'::text,%3)";
        sql=sql.arg(id()).arg(causes()).arg(num());
        DbConnection::QueryResult res = dynamic_cast<TreeDoc*>(treeWidget())->execute(sql);
        ok=res.success();
    }
    if(ok)setChanged(false);
    int i=0;
    while(ok&&!stop)
    {
        stop=(i>=childCount());
        if(!stop) ok=dynamic_cast<DocEntity*>(child(i))->saveToDB();
        i++;
    }
    if(!ok) return false;
    return ok;
}
bool Protocol::isCorrect()
{
    return true;
}
Action* Protocol::owner()
{
    return m_owner;
}
bool Protocol::isCompleted()
{
    return state()==340;
}
void Protocol::approve()
{
    if(!checkCode())
    {
         emit stateMessage(tr("Утверждение протокола не выполнено."),5000);
         return;
    }
    dynamic_cast<TreeDoc*>(treeWidget())->execute(tr("select =schema=.ex_approve(%1)").arg(id()));
    refresh(Himself);
    emit childWakedUp(this);
    emit stateMessage(tr("Операция успешно завершена."),5000);
}
void Protocol::check()
{
    if(!checkCode())
    {
         emit stateMessage(tr("Проверка протокола не выполнена."),5000);
         return;
    }
    dynamic_cast<TreeDoc*>(treeWidget())->execute(tr("select =schema=.ex_checked(%1)").arg(id()));
    refresh(Himself);
    emit childWakedUp(this);
    emit stateMessage(tr("Операция успешно завершена."),5000);
}
